package edu.cs.usask.ca.silver.plugin.rcp.views.projectviewer;

import java.io.File;

import org.apache.log4j.Logger;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.handlers.IHandlerService;

import edu.cs.usask.ca.silver.businesslogic.ids.GroupID;
import edu.cs.usask.ca.silver.businesslogic.ids.ModelProjectID;
import edu.cs.usask.ca.silver.businesslogic.ids.ModelVersionID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioCollectionID;
import edu.cs.usask.ca.silver.exceptions.UnableToInitializeStorageException;
import edu.cs.usask.ca.silver.plugin.rcp.components.SilverPreferenceEntries;
import edu.cs.usask.ca.silver.plugin.rcp.components.SilverTreeObject;
import edu.cs.usask.ca.silver.plugin.rcp.dao.SilverBusinessLogicController;
import edu.cs.usask.ca.silver.plugin.rcp.jobs.LoggerReportScheduler;

/**
 * ProjectView will initialized with local database connection.
 * 
 * @author Yudi Xue
 * 
 */
public class ProjectView extends AbstractProjectView {
	public static final String ID = "edu.cs.usask.ca.silver.plugin.rcp.projectview";
	private static Logger logger = Logger.getLogger(ProjectView.class);

	@Override
	protected void initializeAssociatedStorageAndTreeRootObject() {
		try {
			this.storage = SilverBusinessLogicController.getLocalDerbyStorage();
			this.storage.initializeStorage();
		} catch (UnableToInitializeStorageException ste) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"Failed to initialize local storage at start up", ste);
		} catch (Exception e2) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"error in ProjectView", e2);
		}

		if (!SilverBusinessLogicController
				.checkIfHasUserInformationInPreference()) {
			registerANewUserToLocalDatabase();
		}

		try {
			this.userid = SilverBusinessLogicController
					.fetchUserIDfromDatabaseByPreferenceInfo(this.storage);
			this.silverTreeRoot = new SilverTreeObject(this.userid);
		} catch (NullPointerException e) {
			LoggerReportScheduler.scheduleErrorLogging(logger, e.getMessage(),
					e);
		} catch (Exception e1) {
			LoggerReportScheduler.scheduleErrorLogging(logger, e1.getMessage(),
					e1);
		}
		startMonitorDatabaseJob(ID, 4);
		checkAndLoadVensimDLL();
	}

	private void checkAndLoadVensimDLL() {
		final String path = SilverBusinessLogicController
				.getPreferenceEntry(SilverPreferenceEntries.VENDLL32);
		File temp = new File(path);
		if (temp.canRead()) {
			try {
			SilverBusinessLogicController.loadVensimDLL(path);
			} catch (java.lang.UnsatisfiedLinkError e) {
				MessageDialog.openInformation(this.getSite().getShell(), "Unable to load VensimDLL", "SILVER can not load Vensim DLL from specified file;\nPlease ensure that Vensim DLL is set properly.");
			}
		}
	}

	private void registerANewUserToLocalDatabase() {
		IHandlerService handlerService = (IHandlerService) getSite()
				.getWorkbenchWindow().getWorkbench()
				.getService(IHandlerService.class);
		try {
			handlerService
					.executeCommand(
							"edu.cs.usask.ca.silver.plugin.rcp.handlers.CreateUserCommand",
							null);
		} catch (ExecutionException e) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"error in ProjectView", e);
		} catch (NotDefinedException e) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"error in ProjectView", e);
		} catch (NotEnabledException e) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"error in ProjectView", e);
		} catch (NotHandledException e) {
			LoggerReportScheduler.scheduleErrorLogging(logger,
					"error in ProjectView", e);
		}
	}

	private void addDataToLocalDB() throws Exception {

		if (SilverBusinessLogicController
				.checkIfHasUserInformationInPreference()) {
			GroupID[] list = SilverBusinessLogicController.borrowUserObject()
					.getParticipatedGroupIds(this.userid, this.storage);
			ModelProjectID mpId = SilverBusinessLogicController
					.borrowMpObject().createGenericModelProject(list[0],
							"model project 1", "yudi", "aoeuaoe", null,
							this.storage);

			SilverBusinessLogicController.borrowMpObject()
					.createGenericModelProject(list[0], "model project 2",
							"yudi", "aoeuaoe", null, this.storage);
			ModelVersionID mvId = SilverBusinessLogicController
					.borrowMvObject().createGenericModelVersion("mv 1", "yudi",
							"aaoe aeu", mpId, this.storage);
			ScenarioCollectionID scId = SilverBusinessLogicController
					.borrowScObject().createScenarioCollection(
							"a scenario collection", "yudi", "aeuaoe", mvId,
							this.storage);

			SilverBusinessLogicController.borrowScenario()
					.createGenericScenarioAndParameterSet("scenario1", "yudi",
							"description", mvId, scId, this.storage);
			SilverBusinessLogicController.borrowScenario()
					.createGenericScenarioAndParameterSet("scenario2", "yudi",
							"description", mvId, scId, this.storage);
			SilverBusinessLogicController.borrowScenario()
					.createGenericScenarioAndParameterSet("scenario3", "yudi",
							"description", mvId, scId, this.storage);
			SilverBusinessLogicController.borrowScenario()
					.createGenericScenarioAndParameterSet("scenario4", "yudi",
							"description", mvId, scId, this.storage);
		}
	}

}